/* Definitions of target machine characteristics for GNU C compiler.
   VAX version.
   Copyright (C) 1984 by Richard M. Stallman.

   This will be free software eventually, but not until it is finished.  */

/* Define this if most significant byte of a word is the lowest numbered.  */
/* That is not true on the vax.  */
/* #define BIG_ENDIAN */

/* target machine register layout */
#define FIRST_PSEUDO_REGISTER 16

/* Registers available for general temporary use.  */
#define FIXED_REGISTERS {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}

/* Registers available for use that are not clobbered by calls.  */
#define CALL_USED_REGISTERS {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1}

/* Order in which registers should be allocated.  */
#define ALLOCATE_REGISTERS {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}

/* Order in which registers should be vacated for use for indexing.  */
#define SPILL_REGISTERS {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}

/* target machine storage layout */
/* @@ Source should be checked to see if all of these are still used. */
#define BITS_PER_UNIT	8
	/* number of bits in an addressible storage unit */
#define BITS_PER_HALF_WORD	16
#define BITS_PER_WORD	32
         /* number of bits in a word, preferred allocation boundary */
#define BITS_PER_DOUBLE_WORD	64
#define BITS_PER_TETRA_WORD	128

/* @@ Source should be checked to see if all of these are still used. */
#define POINTER_SIZE	BITS_PER_WORD
	/* size and allocation boundary of a pointer */
#define DOUBLE_POINTER_SIZE	BITS_PER_DOUBLE_WORD
#define POINTER_BOUNDARY	32

/* All function parameters must appear on at least this boundary
   within the parameter list.  */
#define PARM_BOUNDARY		32

/* There is no point aligning anything to a rounder boundary than this.  */
#define BIGGEST_ALIGNMENT	32


#define CASE_VECTOR_MODE HImode

#define CASE_VECTOR_PC_RELATIVE

#define PC_REGNUM 15

#define STACK_POINTER_REGNUM 14

#define FRAME_POINTER_REGNUM 13

#define ARG_POINTER_REGNUM 12

#define STATIC_CHAIN_REGNUM 0

#define FUNCTION_VALUE_REGNUM 0

/* Define this if pushing a word on the stack
   makes the stack pointer a smaller address.  */
#define STACK_GROWS_DOWNWARD

/* Define this if the nominal address of the stack frame
   is at the high-address end of the local variables;
   that is, each additional local variable allocated
   goes at a more negative offset in the frame.  */
#define FRAME_GROWS_DOWNWARD

/* Offset within stack frame to start allocating local variables at.
   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
   first local allocated.  Otherwise, it is the offset to the BEGINNING
   of the first local allocated.  */
#define STARTING_FRAME_OFFSET 0

/* Offset of first parameter from the argument pointer register value.  */
#define FIRST_PARM_OFFSET 4

/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
   that is a valid memory address for an instruction.
   The MODE argument is the machine mode for the MEM expression
   that wants to use this address.

   The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
   except for CONSTANT_ADDRESS_P which is used in constant_address_p().
   CONSTANT_ADDRESS_P is actually machine-independent.  */

/* These are subroutines for the caller to redefine, if appropriate,
   to return nonzero only for REG rtx's that will map into hard registers,
   and zero for those that are relegated to memory.
   You can assume that the argument to this macro has code REG.  */
#define REG_OK_FOR_INDEX_P(X) 1
#define REG_OK_FOR_BASE_P(X) 1

#define CONSTANT_ADDRESS_P(X)   \
  (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF		\
   || GET_CODE (X) == CONST_INT						\
   || ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS)			\
       && constant_address_p (FORMAT_e (X, 0))				\
       && constant_address_p (FORMAT_e (X, 1))))

#define INDIRECTABLE_ADDRESS_P(X)  \
  (CONSTANT_ADDRESS_P (X)						\
   || (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
   || (GET_CODE (X) == PLUS						\
       && GET_CODE (FORMAT_e (X, 0)) == REG				\
       && REG_OK_FOR_BASE_P (FORMAT_e (X, 0))				\
       && constant_address_p (FORMAT_e (X, 1))))

#define GO_IF_NONINDEXED_ADDRESS(X, ADDR)  \
{ register rtx arg;							\
  if (GET_CODE (X) == REG) goto ADDR;					\
  if (INDIRECTABLE_ADDRESS_P (X)) goto ADDR;				\
  arg = FORMAT_e (X, 0);						\
  if ((GET_CODE (X) == MEM && INDIRECTABLE_ADDRESS_P (arg))		\
      || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_INC)		\
	  && GET_CODE (arg) == REG && REG_OK_FOR_BASE_P (arg)))		\
    goto ADDR; }

#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)  \
{ GO_IF_NONINDEXED_ADDRESS (X, ADDR);					\
  if (GET_CODE (X) == PLUS && GET_CODE (FORMAT_e (X, 0)) == MULT	\
      && GET_CODE (FORMAT_e (FORMAT_e (X, 0), 0)) == REG		\
      && REG_OK_FOR_INDEX_P (FORMAT_e (FORMAT_e (X, 0), 0))		\
      && GET_CODE (FORMAT_e (FORMAT_e (X, 0), 1)) == CONST_INT		\
      && FORMAT_i (FORMAT_e (FORMAT_e (X, 0), 1), 0) == GET_MODE_SIZE(MODE))\
    GO_IF_NONINDEXED_ADDRESS (FORMAT_e (X, 1), ADDR);			\
  if (1 == GET_MODE_SIZE (MODE))					\
    {									\
      if (GET_CODE (X) == PLUS						\
	  && GET_CODE (FORMAT_e (X, 0)) == REG				\
	  && REG_OK_FOR_INDEX_P (FORMAT_e (X, 0)))			\
	{ GO_IF_NONINDEXED_ADDRESS (FORMAT_e (X, 1), ADDR); }		\
      else if (GET_CODE (X) == PLUS					\
	       && GET_CODE (FORMAT_e (X, 1)) == REG			\
	       && REG_OK_FOR_INDEX_P (FORMAT_e (X, 1)))			\
	{ GO_IF_NONINDEXED_ADDRESS (FORMAT_e (X, 0), ADDR); } }}

#define HAVE_POST_INCREMENT
/* #define HAVE_POST_DECREMENT */

#define HAVE_PRE_DECREMENT
/* #define HAVE_PRE_INCREMENT */

#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR

/* A pointer is the same size as a word,
   and the conversion between them is a no-op.  */
#define Pmode SImode

/* A function address in a call instruction
   is a byte address (for indexing purposes)
   so give the MEM rtx a byte's mode.  */
#define FUNCTION_MODE QImode

/* Define if returning from a function call automatically
   pops the arguments described by the number-of-args field in the call.  */
#define RETURN_POPS_ARGS

#define FUNCTION_PROLOGUE(FILE, SIZE)     \
{ register int regno;						\
  register int mask = 0;					\
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)	\
    if (regs_ever_live[regno]) mask |= 1 << regno;		\
  fprintf (FILE, "\t.word 0x%x\n", mask & ~077);		\
  if ((SIZE) >= 64) fprintf (FILE, "\tmovab %d(sp),sp\n", SIZE);\
  else if (SIZE) fprintf (FILE, "\tsubl2 $%d,sp\n", - (SIZE)); }

/* not needed on the vax */
/* #define FUNCTION_EPILOGUE(FILE, SIZE)  */

#define REGISTER_NAMES \
{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", \
 "r9", "r10", "r11", "ap", "fp", "sp", "pc"}

/* Number of bytes of boundary to align beginnings of functions on.  */

#define FUNCTION_ALIGN 2

/* Store in CCVAR0 and CCVAR1 the expressions
   that the condition codes will describe
   after execution of an instruction whose pattern is EXP.
   Two variables are provided so two different equivalent expressions
   can be stored (they have the same value, so either could be tested).
   Set CCVAR0 and CCVAR1 to zero if the CC's will be undefined then.
   Do not alter them if the instruction would not alter the cc's.  */

#define NOTICE_UPDATE_CC(CCVAR0,CCVAR1,EXP) \
{ if (GET_CODE (EXP) == SET)					\
    { if (GET_CODE (FORMAT_e (EXP, 0)) != PC)			\
	{ CCVAR0 = FORMAT_e (EXP, 0);				\
	  CCVAR1 = FORMAT_e (EXP, 1); } }			\
  else if (GET_CODE (EXP) == PARALLEL				\
	   && GET_CODE (FORMAT_E (EXP, 0, 0)) == SET)		\
    { if (GET_CODE (FORMAT_e (FORMAT_E (EXP, 0, 0), 0)) != PC)	\
	{ CCVAR0 = FORMAT_e (FORMAT_E (EXP, 0, 0), 0);		\
	  CCVAR1 = FORMAT_e (FORMAT_E (EXP, 0, 0), 1); } }	\
  else CCVAR0 = 0, CCVAR1 = 0; }

/* Define the classes of registers.
   One of the classes must always be named ALL_REGS and include all hard regs.
   If there is more than one class, another class must be named NO_REGS
   and contain none of the registers.

   The classes must be numbered in nondecreasing order; that is,
   a larger-numbered class must never be contained completely
   in a smaller-numbered class.

   For any two classes, it is very desirable that there be another
   class that represents their union.  */
   
/* The Vax has only one class of registers, which includes all of them.  */

enum reg_class { ALL_REGS, LIM_REG_CLASSES };

#define N_REG_CLASSES (int) LIM_REG_CLASSES

/* Define which registers fit in which classes.
   This is an initializer for a vector of HARD_REG_SET
   of length N_REG_CLASSES.  */

#define REG_CLASS_CONTENTS {0xffff}

/* The same information, inverted:
   Return the class number of the smallest class containing
   reg number REGNO.  This could be a conditional expression
   or could index an array.  */

#define REGNO_REG_CLASS(REGNO) ALL_REGS

/* Define a table that lets us find quickly all the reg classes
   containing a given one.  This is the initializer for an
   N_REG_CLASSES x N_REG_CLASSES array of reg class codes.
   Row N is a sequence containing all the class codes for
   classes that contain all the regs in class N.  Each row
   contains no duplicates, and is terminated by a -1.  */
   
#define REG_CLASS_SUPERCLASSES {{(enum reg_class) -1}}

/* Define a table that lets us find quickly the class
   for the subunion of any two classes.

   We say "Subunion" because the result need not be exactly
   the union; it may instead be a subclass of the union
   (though the closer to the union, the better).
   But if it contains anything beyond union of the two classes,
   you will lose!

   This is an initializer for an N_REG_CLASSES x N_REG_CLASSES
   array of reg class codes.  The subunion of classes C1 and C2
   is just element [C1, C2].  */


#define REG_CLASS_SUBUNION {{ALL_REGS}}

/* The class value for index registers, and the one for base regs.  */

#define INDEX_REG_CLASS ALL_REGS
#define BASE_REG_CLASS ALL_REGS

/*
Local variables:
version-control: t
End:
*/
